#include "StdAfx.h"
#include "ChorusInstrument.h"
#include "ToneInstrument.h"
#include "Note.h"
#include "Notes.h"




CChorusInstrument::CChorusInstrument(void)
{
	mQueue.resize(200);
	mPeriod = 0;
	k = 0;
}


CChorusInstrument::~CChorusInstrument(void)
{
}

void CChorusInstrument::Start()
{
	mSinewave.SetSampleRate( GetSampleRate() );
	mSinewave.Start();
	mTime = 0;

	mAr.SetSource(&mSinewave);
	mAr.SetSampleRate(GetSampleRate());
	mAr.SetBeatsPerMinute(GetBPM());
	mAr.Start();

}

bool CChorusInstrument::Generate()
{
	// Tell the component to generate an audio sample
	
    mSinewave.Generate();
	bool lValid = mAr.Generate();
	
	double bps = 1 / (mBPM/60);


    // Read the component's sample and make it our resulting frame.
	mFrameCopy[0] = mFrame[0];
	mFrameCopy[1] = mFrame[1];

    mPeriod++;

	k = mPeriod / GetSampleRate();
	
    mFrame[0] = mAr.Frame(0) +  mFrame[0]* sin( 2* 3.14 * mPeriod);
    mFrame[1] = mAr.Frame(1) +  mFrame[1]* sin(2 * 3.14 *mPeriod);


    // Update time
    mTime += GetSamplePeriod();

    // We return true until the time reaches the duration.
    return lValid;
}

void CChorusInstrument::SetNote( CNote *aNote )
{
	// Get a list of all attribute nodes and the
    // length of that list
    CComPtr<IXMLDOMNamedNodeMap> attributes;
    aNote->Node()->get_attributes(&attributes);
    long len;
    attributes->get_length(&len);

    // Loop over the list of attributes
    for(int i=0;  i<len;  i++)
    {
        // Get attribute i
        CComPtr<IXMLDOMNode> attrib;
        attributes->get_item(i, &attrib);

        // Get the name of the attribute
        CComBSTR name;
        attrib->get_nodeName(&name);

        // Get the value of the attribute.  A CComVariant is a variable
        // that can have any type. It loads the attribute value as a
        // string (UNICODE), but we can then change it to an integer 
        // (VT_I4) or double (VT_R8) using the ChangeType function 
        // and then read its integer or double value from a member variable.
        CComVariant value;
        attrib->get_nodeValue(&value);

        if(name == "duration")
        {
            value.ChangeType(VT_R8);
            SetDuration(value.dblVal);
        }
		else if(name == "note")
        {
            SetFreq(NoteToFrequency(value.bstrVal));
        }
		else if(name =="wet")
		{
			//SetFrameCopyFreq(NoteToFrequency(value.bstrVal) + 50.0);
			SetWet(value.dblVal); // wet or dry amplitude - hardcoded for now
		}
    }
}